#include <commandSetAddressBySN.h>
#include <deviceParameter.h>
#include <commandList.h>

#if COMMAND_MASTER_CALL_DEFINE
int masterCallbackSetAddressBySN(void *inputstring, uint32_t *inputsize, void *userdata)
{
    struct protocolPackageCommonInform *tmppack = (struct protocolPackageCommonInform *)inputstring;
    struct commandCommonStruct *tmpcommand = (struct commandCommonStruct *)tmppack->pv2.v2Data;
    struct deviceStructSetAddressBySN *tmpinform = (struct deviceStructSetAddressBySN *)tmpcommand->commandData;
    // struct protocolProcessorInform *tmpprocessor = (struct protocolProcessorInform *)userdata;
    if (!inputstring || !inputsize || !userdata)
    {
        logerror("");
        return -1;
    }
    logdebug("device[%d]'s ,sn=%.*s, addr=%d", tmppack->pv2.v2SourceAddr,
             (int)sizeof(tmpinform->responseSn), tmpinform->responseSn, tmpinform->responseAddr);
    return 0;
}
int masterWaitResponseSetAddressBySN(struct protocolProcessorInform *processer, struct masterStructSetAddressBySN *indata,
                                     uint16_t insize, uint8_t devaddr)
{
    int tmpflag = 0;
    if (!processer || !devaddr)
    {
        logerror("");
        return -1;
    }
    uint8_t tmpPackBuffer[PROTOCOL_PACK_MAX_SIZE];
    struct protocolPackageCommonInform *tmppack = (struct protocolPackageCommonInform *)tmpPackBuffer;
    struct commandCommonStruct *tmpcommand = (struct commandCommonStruct *)tmppack->pv2.v2Data;
    if ((PROTOCOL_V2_COMMON_HEAD_SIZE + PROTOCOL_V2_DATA_SIZE(insize)) > sizeof(tmpPackBuffer))
    {
        logerror("data big:%d", (int)PROTOCOL_V2_DATA_SIZE(insize));
        return 0;
    }
    processer->commandExcuterAddr = devaddr;
    processer->commandExcuter.command = commandIdSetAddrBySN;
    processer->commandExcuter.serialNumber = generateCommandSerial();
    processer->commandExcuter.responseFlag = commandExcuteResultUnkown;
    memcpy(tmpcommand, &processer->commandExcuter, PROTOCOL_COMMAND_COMMON_HEAD_SIZE);
    memcpy(tmpcommand->commandData, indata, insize);
    tmppack->pv2.v2DataSize = PROTOCOL_V2_DATA_SIZE(insize);
    tmpflag = processerPackageProtocolData(processer, tmpPackBuffer, sizeof(tmpPackBuffer));
    if (tmpflag <= 0)
    {
        logerror("");
        return -1;
    }
    masterProcesserSetReTryCount(processer, 0);
    masterProcesserSetTimeout(processer, 200);
    tmpflag = masterProcesserSendAndWaitResponse(processer, tmpPackBuffer, tmpflag);
    return tmpflag;
}
#endif

#if COMMAND_DEVICE_CALL_DEFINE
struct deviceParameterOperate *deviceParamOperatePcCheckInstance();
int deviceCallbackSetAddressBySN(void *inputstring, uint32_t *inputsize, void *userdata)
{
    struct protocolPackageCommonInform *tmppack = (struct protocolPackageCommonInform *)inputstring;
    // struct protocolVersion2 *tmpv2 = &tmppack->pv2;
    struct commandCommonStruct *tmpcommand = (struct commandCommonStruct *)tmppack->pv2.v2Data;
    struct protocolProcessorInform *tmpprocessor = (struct protocolProcessorInform *)userdata;
    struct masterStructSetAddressBySN *tmpCmdData = (struct masterStructSetAddressBySN *)tmpcommand->commandData;
    struct deviceStructSetAddressBySN *tmpResponseData = (struct deviceStructSetAddressBySN *)tmpcommand->commandData;
    int tmpDataSize;
    if (!inputstring || !inputsize || !userdata)
    {
        logerror("");
        return -1;
    }
    tmpDataSize = tmppack->pv2.v2DataSize - PROTOCOL_COMMAND_COMMON_HEAD_SIZE;
    if (tmpDataSize != sizeof(struct masterStructSetAddressBySN))
    {
        logerror("input data error :%d, %d", tmpDataSize, (int)sizeof(struct masterStructSetAddressBySN));
        return -1;
    }
    if (sizeof(struct deviceStructSetAddressBySN) > PROTOCOL_V2_COMMAND_DATA_SIZE)
    {
        logerror("size error:%d>%d", (int)sizeof(struct deviceStructSetAddressBySN), (int)PROTOCOL_V2_COMMAND_DATA_SIZE);
        return -1;
    }

    logdebug("master set:%.*s,%d", sizeof(tmpCmdData->setSn), tmpCmdData->setSn, tmpCmdData->setaddr);
    if (memcmp(tmpCmdData->setSn, devNorParmInst()->deviceSerialNumber, sizeof(tmpCmdData->setSn)))
    {
        logdebug("sn not match :%.*s, %.*s", sizeof(tmpCmdData->setSn), tmpCmdData->setSn,
                 sizeof(tmpCmdData->setSn), devNorParmInst()->deviceSerialNumber);
        return -1;
    }

    logdebug("master set:my=%d,set=%d", devNorParmInst()->device485Addr, tmpCmdData->setaddr);
    devNorParmInst()->device485Addr = tmpCmdData->setaddr;
    deviceParamWriteToHard(deviceParamOperatePcCheckInstance());
    tmpprocessor->communicateInform.my485Addr = devNorParmInst()->device485Addr;

    inputsize[0] = sizeof(struct deviceStructSetAddressBySN);
    memcpypro(tmpResponseData->responseSn, sizeof(tmpResponseData->responseSn),
              devNorParmInst()->deviceSerialNumber, sizeof(devNorParmInst()->deviceSerialNumber));
    tmpResponseData->responseAddr = devNorParmInst()->device485Addr;

    return commandExcuteResultOk;
}
#endif